package com.zhijian.medical.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import com.zhijian.medical.dao.local.DoctorAdviceMapper;
import com.zhijian.medical.entity.po.DoctorAdvice;
import com.zhijian.medical.entity.po.ExperimentProcessSample;
import com.zhijian.medical.entity.po.SpecialInstruction;
import com.zhijian.medical.entity.vo.request.DoctorAdviceSaveOrUpdateVo;
import com.zhijian.medical.entity.vo.request.DoctorAdviceSearchVo;
import com.zhijian.medical.entity.vo.request.SpecialInstructionSearchVo;
import com.zhijian.medical.entity.vo.response.DoctorAdviceVo;
import com.zhijian.medical.entity.vo.response.SpecialInstructionVo;
import com.zhijian.medical.enums.ExperimentProcessSampleWeatherQualifiedEnum;
import com.zhijian.medical.holder.CurrentUserHolder;
import com.zhijian.medical.service.DoctorAdviceService;
import com.zhijian.medical.service.ExperimentProcessSampleService;
import com.zhijian.medical.service.SpecialInstructionService;
import com.zhijian.medical.util.AssertUtil;
import com.zhijian.medical.util.Page;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;

/**
 * 医嘱业务处理层
 *
 * @author HCG
 * @version: 1.0
 * @date 2023-08-06 22:11:04
 */
@Slf4j
@Service
public class DoctorAdviceServiceImpl implements DoctorAdviceService {

    @Autowired
    private DoctorAdviceMapper mapper;

    @Autowired
    private ExperimentProcessSampleService experimentProcessSampleService;
    @Autowired
    private SpecialInstructionService specialInstructionService;

    @Override
    public DoctorAdvice selectById(Long id) {
        return mapper.selectByPrimaryKey(id);
    }

    @Override
    public DoctorAdviceVo selectVoById(Long id) {
        return mapper.selectVoById(id);
    }

    @Override
    public void deleteById(Long id) {
        mapper.deleteByPrimaryKey(id);
    }

    @Override
    public Long insert(DoctorAdvice doctorAdvice) {
        Date now = new Date();
        doctorAdvice.setCreateTime(now);
        doctorAdvice.setUpdateTime(now);
        return mapper.insert(doctorAdvice) > 0 ? doctorAdvice.getId() : 0L;
    }

    @Override
    public boolean update(DoctorAdvice doctorAdvice) {
        Date now = new Date();
        doctorAdvice.setUpdateTime(now);
        return mapper.updateByPrimaryKey(doctorAdvice) != 0;
    }

    @Override
    public boolean updateByPrimaryKeySelective(DoctorAdvice record) {
        Date now = new Date();
        record.setUpdateTime(now);
        return mapper.updateByPrimaryKeySelective(record) != 0;
    }

    @Override
    public Integer count(DoctorAdviceSearchVo doctorAdviceSearchVo) {
        return mapper.count(doctorAdviceSearchVo);
    }

    @Override
    public List<DoctorAdviceVo> selectList(DoctorAdviceSearchVo doctorAdviceSearchVo) {
        return mapper.selectList(doctorAdviceSearchVo);
    }

    @Override
    public Page<DoctorAdviceVo> selectPage(DoctorAdviceSearchVo doctorAdviceSearchVo) {
        //先直接查总数
        int count = count(doctorAdviceSearchVo);
        //分页
        Page<DoctorAdviceVo> page = new Page<>(true, count, doctorAdviceSearchVo.getPageNum(), doctorAdviceSearchVo.getPageSize());
        doctorAdviceSearchVo.setStartIndex(page.getStartIndex());
        page.setPage(true);
        page.setTotalCount(count);
        List<DoctorAdviceVo> responseVos = this.selectList(doctorAdviceSearchVo);
        page.setData(responseVos);
        return page;
    }

    @Override
    public boolean insertBatch(List<DoctorAdvice> entities) {
        return CollectionUtil.isNotEmpty(entities) && mapper.insertBatch(entities) > 0;
    }

    @Transactional(rollbackFor = Exception.class, value = "localTransactionManager")
    @Override
    public boolean execute(Long id) {
        DoctorAdvice doctorAdvice = this.selectById(id);
        AssertUtil.notNull(doctorAdvice, "此医嘱不存在或者已被删除");

        Date now = new Date();
        ExperimentProcessSample experimentProcessSample = new ExperimentProcessSample();
        BeanUtils.copyProperties(doctorAdvice, experimentProcessSample);
        //样本类型
        experimentProcessSample.setType(doctorAdvice.getSampleType());
        //接收人
        experimentProcessSample.setReceiveUser(CurrentUserHolder.getUser().getName());
        // 医嘱中的执行状态修改
        List<SpecialInstructionVo> specialInstructionVos = specialInstructionService.selectList(SpecialInstructionSearchVo.builder().waxBlock(doctorAdvice.getCode()).build());
        for (SpecialInstructionVo specialInstructionVo : specialInstructionVos) {
            specialInstructionService.updateByPrimaryKeySelective(SpecialInstruction.builder()
                    .id(specialInstructionVo.getId())
                    .status((byte) 1)
                    .build());
        }

        //默认合格
        experimentProcessSample.setWeatherQualified(ExperimentProcessSampleWeatherQualifiedEnum.HG.getCode().byteValue());
        experimentProcessSample.setReceiveDate(now);
        experimentProcessSampleService.insert(experimentProcessSample);
        return this.updateByPrimaryKeySelective(DoctorAdvice.builder()
                .id(id)
                .executeTime(now)
                .status((byte) 1)
                .build());
    }

    @Override
    public boolean back(Long id, String backReason) {
        DoctorAdvice doctorAdvice = this.selectById(id);
        AssertUtil.notNull(doctorAdvice, "此医嘱不存在或者已被删除");
        doctorAdvice.setStatus((byte) 0);
        doctorAdvice.setBackReason(backReason);
        return this.update(doctorAdvice);
    }

    @Override
    public boolean save(DoctorAdviceSaveOrUpdateVo doctorAdviceSaveOrUpdateVo) {
        DoctorAdvice doctorAdvice = new DoctorAdvice();
        BeanUtils.copyProperties(doctorAdviceSaveOrUpdateVo, doctorAdvice);
        if (StringUtils.isNotBlank(doctorAdviceSaveOrUpdateVo.getIssueTime())) {
            doctorAdvice.setIssueTime(DateUtil.parseDateTime(doctorAdviceSaveOrUpdateVo.getIssueTime()));
        }
        if (StringUtils.isNotBlank(doctorAdviceSaveOrUpdateVo.getSampleGatherTime())) {
            doctorAdvice.setSampleGatherTime(DateUtil.parseDateTime(doctorAdviceSaveOrUpdateVo.getSampleGatherTime()));
        }
        //默认未执行
        doctorAdvice.setStatus((byte) 0);
        return this.insert(doctorAdvice) != 0;
    }

    @Override
    public boolean update(DoctorAdviceSaveOrUpdateVo doctorAdviceSaveOrUpdateVo) {
        DoctorAdvice doctorAdvice = new DoctorAdvice();
        BeanUtils.copyProperties(doctorAdviceSaveOrUpdateVo, doctorAdvice);
        if (StringUtils.isNotBlank(doctorAdviceSaveOrUpdateVo.getIssueTime())) {
            doctorAdvice.setIssueTime(DateUtil.parseDateTime(doctorAdviceSaveOrUpdateVo.getIssueTime()));
        }
        if (StringUtils.isNotBlank(doctorAdviceSaveOrUpdateVo.getSampleGatherTime())) {
            doctorAdvice.setSampleGatherTime(DateUtil.parseDateTime(doctorAdviceSaveOrUpdateVo.getSampleGatherTime()));
        }
        return this.updateByPrimaryKeySelective(doctorAdvice);
    }

}